package com.plan.code;

import org.apache.commons.lang.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.function.ToIntBiFunction;

/**
 * @description: 并列if-else语句优化(表驱动)
 * @author: admin
 * @time: 2022/12/7 21:07
 */
public class IfElse03 {

    public static void main(String[] args) {

        String strDay = "Fri";
        //优化前的方法
        System.out.println("优化前的方法调用" + formatDay(strDay));
        //优化后的方法
        System.out.println("优化后的方法调用" + formatDayOptimization(strDay));
        //Lambda表达式
        System.out.println("Lambda优化后的方法调用" + formatDayOptimizationLambda(strDay));
        String command = "add";
        int num1 = 8;
        int num2 = 4;
        //优化前的方法
        System.out.println("两个数字优化前的方法调用" + calculate(command, num1, num2));

        //优化后的方法
        System.out.println("两个数字优化后的方法调用" + calculateOptimization(command, num1, num2));
    }

    /**
     * 没有优化前的代码
     */
    public static String formatDay(String str) {
        if ("Mon".equals(str)) {
            return "Monday";
        } else if ("Tue".equals(str)) {
            return "Tuesday";
        } else if ("Wed".equals(str)) {
            return "Wednesday";
        } else if ("Thu".equals(str)) {
            return "Thursday";
        } else if ("Fri".equals(str)) {
            return "Friday";
        } else if ("Sat".equals(str)) {
            return "Saturday";
        } else if ("Sun".equals(str)) {
            return "Sunday";
        } else {
            return "Unknown";
        }
    }

    /**
     * 优化后的代码
     *
     * @param str
     * @return
     */
    public static String formatDayOptimization(String str) {
        Map<String, String> map = new HashMap<>(7);
        map.put("Mon", "Monday");
        map.put("Tue", "Tuesday");
        map.put("Wed", "Wednesday");
        map.put("Thu", "Thursday");
        map.put("Fri", "Friday");
        map.put("Sat", "Saturday");
        map.put("Sun", "Sunday");
        String day = map.get(str);
        return StringUtils.isNotBlank(day) ? day : "Unknown";
    }

    /**
     * 优化后的代码
     *
     * @param str
     * @return
     */
    public static String formatDayOptimizationLambda(String str) {
        if (StringUtils.isBlank(str)) {
            return "Unknown";
        }
        Map<String, Supplier<String>> mapSupplier = new HashMap<>(7);
        mapSupplier.put("Mon", () -> "Monday");
        mapSupplier.put("Tue", () -> "Tuesday");
        mapSupplier.put("Wed", () -> "Wednesday");
        mapSupplier.put("Thu", () -> "Thursday");
        mapSupplier.put("Fri", () -> "Friday");
        mapSupplier.put("Sat", () -> "Saturday");
        mapSupplier.put("Sun", () -> "Sunday");
        return Optional.ofNullable(mapSupplier.get(str))
                .orElse(()-> "Unknown")
                .get();
    }


    /**
     * 优化前的方法
     *
     * @param command
     * @param num1
     * @param num2
     * @return
     */
    public static int calculate(String command, int num1, int num2) {
        if (StringUtils.isBlank(command)) {
            return -1;
        }
        if ("add".equals(command)) {
            return num1 + num2;
        } else if ("sub".equals(command)) {
            return num1 - num2;
        } else if ("mul".equals(command)) {
            return num1 * num2;
        } else if ("div".equals(command)) {
            return num1 / num2;
        } else {
            return -1;
        }

    }

    /**
     * 优化后的代码
     *
     * @param command
     * @param num1
     * @param num2
     * @return
     */
    public static int calculateOptimization(String command, int num1, int num2) {
        if (StringUtils.isBlank(command)) {
            return -1;
        }
        Map<String, ToIntBiFunction<Integer, Integer>> mapFunction = new HashMap<>(4);
        mapFunction.put("add", Integer::sum);
        mapFunction.put("sub", (a, b) -> a - b);
        mapFunction.put("mul", (a, b) -> a * b);
        mapFunction.put("div", (a, b) -> a / b);
        return Optional.ofNullable(mapFunction.get(command))
                .orElse((a, b) -> -1)
                .applyAsInt(num1, num2);
    }
}
